package com.baitiaojun.elasticsearch.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baitiaojun.api.domain.video.Video;
import com.baitiaojun.api.domain.video.VideoChildComment;
import com.baitiaojun.api.domain.video.VideoComment;
import com.baitiaojun.api.exception.ConditionException;
import com.baitiaojun.api.vo.PageInfo;
import com.baitiaojun.elasticsearch.repository.VideoChildCommentRepository;
import com.baitiaojun.elasticsearch.repository.VideoCommentRepository;
import com.baitiaojun.elasticsearch.service.VideoCommentService;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.ObjectUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.index.query.TermsQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.query.DeleteQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @类名 VideoCommentServiceImpl
 * @描述 TODO
 * @作者 白条君
 * @创建日期 2022/12/26 21:29
 * @版本 1.0
 */
@Service
public class VideoCommentServiceImpl implements VideoCommentService {

    @Resource
    private VideoCommentRepository videoCommentRepository;

    @Resource
    private VideoChildCommentRepository videoChildCommentRepository;

    @Autowired
    private ElasticsearchRestTemplate restTemplate;

    @Autowired
    private RestHighLevelClient client;

    @Override
    public void saveParentVideoComment(VideoComment videoComment) throws ConditionException {
        VideoComment resVideoComment = videoCommentRepository.save(videoComment);
        if (ObjectUtils.isEmpty(resVideoComment)) {
            throw new ConditionException("一级评论添加到es失败");
        }
    }

    @Override
    public VideoComment getParentVideoComment(Long id, Long videoId) {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        queryBuilder.must(QueryBuilders.matchQuery("id", id));
        queryBuilder.must(QueryBuilders.matchQuery("videoId", videoId));
        Iterable<VideoComment> videoComments = videoCommentRepository.search(queryBuilder);
        return videoComments.iterator().next();
    }

    @Override
    public List<VideoComment> getParentVideoCommentList(Integer pageNo, Integer pageSize, Long videoId) {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        queryBuilder.mustNot(QueryBuilders.existsQuery("rootid"));
        queryBuilder.must(QueryBuilders.matchQuery("videoId", videoId));
        Sort sort = Sort.by(Sort.Direction.DESC, "createtime");
        int from = pageNo - 1;
        PageRequest request = PageRequest.of(from, pageSize, sort);
        Iterable<VideoComment> videoComments = videoCommentRepository.search(queryBuilder, request);
        return Lists.newArrayList(videoComments);
    }

    @Override
    public List<VideoChildComment> getChildVideoCommentList(Set<Long> ids) throws IOException {
        SearchRequest request = new SearchRequest();
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        TermsQueryBuilder queryBuilder = QueryBuilders.termsQuery("rootid", ids);
        searchSourceBuilder.query(queryBuilder);
        searchSourceBuilder.sort("createtime", SortOrder.DESC);
        request.source(searchSourceBuilder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        List<Map<String, Object>> list = Arrays.stream(response.getHits().getHits()).map(SearchHit::getSourceAsMap).collect(Collectors.toList());
        return JSONObject.parseArray(JSONObject.toJSONString(list), VideoChildComment.class);
    }

    @Override
    public void saveChildVideoComment(VideoChildComment videoChildComment) throws ConditionException {
        VideoChildComment resVideoChildComment = videoChildCommentRepository.save(videoChildComment);
        if (ObjectUtils.isEmpty(resVideoChildComment)) {
            throw new ConditionException("二级评论添加到es失败");
        }
    }

    @Override
    public PageInfo getPageChildVideoCommentList(Integer pageNo, Integer pageSize, Long videoId, Long rootId) {
        BoolQueryBuilder queryBuilder = new BoolQueryBuilder();
        queryBuilder.must(QueryBuilders.matchQuery("videoid", videoId));
        queryBuilder.must(QueryBuilders.matchQuery("rootid", rootId));
        Sort sort = Sort.by(Sort.Direction.DESC, "createtime");
        PageRequest request = PageRequest.of(pageNo - 1, pageSize, sort);
        Page<VideoChildComment> videoChildComments = videoChildCommentRepository.search(queryBuilder, request);
        long totalPages = videoChildComments.getTotalElements();
        return PageInfo.builder().pageList(Lists.newArrayList(videoChildComments)).size(totalPages).build();
    }

    @Override
    public void removeVideoChildComment(Long id) {
        videoChildCommentRepository.deleteById(id);
    }

    @Override
    public void removeVideoComment(Long id) {
        videoCommentRepository.deleteById(id);
        DeleteQuery deleteQuery = new DeleteQuery();
        deleteQuery.setIndex("video_child_comment");
        deleteQuery.setQuery(QueryBuilders.termQuery("rootid", id));
        deleteQuery.setType("videochildcomment");
        restTemplate.delete(deleteQuery);
    }

    @Override
    public VideoChildComment getVideoChildComment(Long id) {
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("id", id);
        Iterable<VideoChildComment> videoChildComments = videoChildCommentRepository.search(termQueryBuilder);
        return videoChildComments.iterator().next();
    }

    @Override
    public List<VideoComment> getVideoCommentList(Long userId) throws IOException {
        SearchRequest searchRequest = new SearchRequest();
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //允许查询返回10000条数据以上
        searchSourceBuilder.trackScores(true);
        searchSourceBuilder.size(10000);
        //条件
        searchSourceBuilder.query(QueryBuilders.termQuery("userId", userId));
        //查找
        searchRequest.indices("video_comment");
        searchRequest.source(searchSourceBuilder);
        SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
        List<Map<String, Object>> list = Arrays.stream(search.getHits().getHits()).map(SearchHit::getSourceAsMap).collect(Collectors.toList());
        return JSONObject.parseArray(JSONObject.toJSONString(list), VideoComment.class);
    }

    @Override
    public List<VideoChildComment> getVideoChildCommentList(Set<Long> ids) {
        TermsQueryBuilder queryBuilder = QueryBuilders.termsQuery("rootid", ids);
        Iterable<VideoChildComment> videoChildComments = videoChildCommentRepository.search(queryBuilder);
        return Lists.newArrayList(videoChildComments);
    }


}